import cv2
import time
import os
import numpy as np

def cv_imread(file_path):
    img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1)
    img = cv2.resize(img,None,fx=0.3, fy=0.3)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    return img


def feature_match(img1_path, img2_path):
    img1 = cv_imread(img1_path)
    img2 = cv_imread(img2_path)
    # img1 = cv2.resize(img1,None,fx=0.3, fy=0.3)



    # 创建sift检测器
    sift = cv2.SIFT_create()
    # 查找监测点和匹配符
    kp1, des1 = sift.detectAndCompute(img1, None)
    kp2, des2 = sift.detectAndCompute(img2, None)
    """
    keypoint是检测到的特征点的列表
    descriptor是检测到特征的局部图像的列表
    """
    # 获取flann匹配器
    FLANN_INDEX_KDTREE = 0
    # 参数1：indexParams
    #    对于SIFT和SURF，可以传入参数index_params=dict(algorithm=FLANN_INDEX_KDTREE, trees=5)。
    #    对于ORB，可以传入参数index_params=dict(algorithm=FLANN_INDEX_LSH, table_number=6, key_size=12）。
    indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
    # indexParams = dict(algorithm=FLANN_INDEX_KDTREE, table_number=6, key_size=12)
    # 参数2：searchParams 指定递归遍历的次数，值越高结果越准确，但是消耗的时间也越多。
    searchParams = dict(checks=50)


    # 使用FlannBasedMatcher 寻找最近邻近似匹配
    flann = cv2.FlannBasedMatcher(indexParams, searchParams)
    # 使用knnMatch匹配处理，并返回匹配matches
    matches = flann.knnMatch(des1, des2, k=2)
    # 通过掩码方式计算有用的点
    matchesMask = [[0, 0] for i in range(len(matches))]
    # 通过描述符的距离进行选择需要的点
    for i, (m, n) in enumerate(matches):
        if m.distance < 0.7*n.distance: # 通过0.7系数来决定匹配的有效关键点数量
            matchesMask[i] = [1, 0]

    drawPrams = dict(
                    matchColor=(0, 255, 0),
                    singlePointColor=(255, 0, 0),
                    matchesMask=matchesMask,
                    flags=2
                    )
    # 匹配结果图片
    result = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **drawPrams)

    cv2.imshow(f'screen', result)

    good_matches = [m for m, n in matches if m.distance < 0.7 * n.distance]

    if len(good_matches) > 10:
        cv2.waitKey(0)
    else: 
        cv2.waitKey(50)
    return good_matches
        



# 记录开始时间
start = time.time()

# 执行代码块
# ...代码
image_extensions = ['.jpg', '.jpeg', '.png']
images_path = []

for root, dirs, files in os.walk("imgs"):
    for file in files:
        if any(file.lower().endswith(ext) for ext in image_extensions):
            images_path.append(os.path.join(root, file))
# plt.show()

for path in images_path:
    print(path)
    feature_match('al.png', path)

    try:
        pass
    except Exception as e:
        print(e)

end = time.time()




# 记录结束时间

# 计算并显示运行时间
print('运行时间: {:.2f} 秒'.format(end - start))